#include "curveWidget.h"
#include <GC_MakeArcOfCircle.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <TopoDS_Edge.hxx>
#include "BRepPrimAPI_MakePrism.hxx"
#include "GC_MakeEllipse.hxx"
#include <vtkNamedColors.h>
#include <Geom_Parabola.hxx>
#include <GC_MakeArcOfParabola.hxx>
#include <gp_Parab.hxx>


curveWidget::curveWidget(modelSoft* myModelSoft, QWidget* parent)
	: myModelSoft(myModelSoft)
	, QWidget(parent)
	, ui(new Ui::curveWidgetClass())
{
	ui->setupUi(this);
	ui->typeSelect->addItem("直线(Line)");
	ui->typeSelect->addItem("圆弧(Arc)");
	ui->typeSelect->addItem("椭圆(Ellipse)");
	ui->typeSelect->addItem("抛物线(Parabola)");

	ui->confirmButton->setEnabled(false);
	ui->modifyButton->setEnabled(false);
	//建立直线拉伸成平面
	gp_Pnt pos1(-1, -1, 0);
	gp_Pnt pos2(1, -1, 0);
	BRepBuilderAPI_MakeEdge edgeShape(pos1, pos2);
	gp_Vec stretchDirection(0, 2, 0);
	const TopoDS_Shape& newShape = BRepPrimAPI_MakePrism(edgeShape, stretchDirection);
	/*stretchPipeline = myModelSoft->CreatePipeline(newShape);
	myModelSoft->myView->getRenderWindow()->Render();*/
	// 创建一个Pipeline
	stretchPipeline = new QIVtkSelectionPipeline(newShape, 10000);
	stretchPipeline->AddToRenderer(myModelSoft->myView->getRenderer());
	vtkNew<vtkNamedColors> colors;
	stretchPipeline->Actor()->GetProperty()->SetColor(colors->GetColor4d("Black").GetData());
	stretchPipeline->Actor()->GetProperty()->SetOpacity(0.5);
	myModelSoft->myView->getInteractorStyle()->addPipeline(stretchPipeline, stretchPipeline->GetShapeID());
	myModelSoft->myView->getRenderer()->Render();
	myModelSoft->myView->getRenderWindow()->Render();

	CreateConnections();
}

curveWidget::~curveWidget()
{
	delete ui;
}

void curveWidget::CreateConnections()
{
	connect(myModelSoft->currVertexSelector, &OccVertexSelector::leftButtonDown, this, &curveWidget::receiveVertexPoint);
	connect(ui->cancelButton, &QPushButton::clicked, this, &curveWidget::close);
	connect(ui->confirmButton, &QPushButton::clicked, this, &curveWidget::OnConfirm);
	connect(ui->modifyButton, &QPushButton::clicked, this, &curveWidget::OnModify);
	connect(ui->vertexCancelSelect, &QPushButton::clicked, this, &curveWidget::OnCancelSelVertex);
	connect(ui->vertexSelect, &QPushButton::clicked, this, &curveWidget::OnSelVertex);
	connect(ui->typeSelect, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &curveWidget::OnBoolOPChange);

}


void curveWidget::receiveVertexPoint(gp_Pnt position)
{
	
	if (type == 0 && receiveVertexNum < 2) {//Line
		vertexPos[receiveVertexNum][0] = position.X();
		vertexPos[receiveVertexNum][1] = position.Y();
		vertexPos[receiveVertexNum][2] = position.Z();
		//可视化接收点
		vertexActors.push_back(myModelSoft->CreateTempSphereActor(0.02f, gp_Pnt(vertexPos[receiveVertexNum][0], vertexPos[receiveVertexNum][1], vertexPos[receiveVertexNum][2])));
		receiveVertexNum++;
		if (receiveVertexNum == 2) ui->modifyButton->setEnabled(true);
	}
	else if (type == 1 && receiveVertexNum < 3) { //Arc
		vertexPos[receiveVertexNum][0] = position.X();
		vertexPos[receiveVertexNum][1] = position.Y();
		vertexPos[receiveVertexNum][2] = position.Z();
		//可视化接收点
		vertexActors.push_back(myModelSoft->CreateTempSphereActor(0.02f, gp_Pnt(vertexPos[receiveVertexNum][0], vertexPos[receiveVertexNum][1], vertexPos[receiveVertexNum][2])));
		receiveVertexNum++;
		if (receiveVertexNum == 3) ui->modifyButton->setEnabled(true);
	}
	else if (type == 2 && receiveVertexNum < 3){ //Ellipse
		vertexPos[receiveVertexNum][0] = position.X();
		vertexPos[receiveVertexNum][1] = position.Y();
		vertexPos[receiveVertexNum][2] = position.Z();
		vertexActors.push_back(myModelSoft->CreateTempSphereActor(0.02f, gp_Pnt(vertexPos[receiveVertexNum][0], vertexPos[receiveVertexNum][1], vertexPos[receiveVertexNum][2])));
		receiveVertexNum++;

		if (receiveVertexNum == 3) ui->modifyButton->setEnabled(true);

	}
	else if (type == 3 && receiveVertexNum < 5) { //Parabola
		vertexPos[receiveVertexNum][0] = position.X();
		vertexPos[receiveVertexNum][1] = position.Y();
		vertexPos[receiveVertexNum][2] = position.Z();
		vertexActors.push_back(myModelSoft->CreateTempSphereActor(0.02f, gp_Pnt(vertexPos[receiveVertexNum][0], vertexPos[receiveVertexNum][1], vertexPos[receiveVertexNum][2])));
		receiveVertexNum++;

		if (receiveVertexNum == 5) ui->modifyButton->setEnabled(true);
	}
}

void curveWidget::closeEvent(QCloseEvent* event)
{
	// 没有点确定，删除创建的Actor
	if (!confirmCreated)
	{
		if (!resultPipeline.IsNull())
		{
			myModelSoft->RemovePipelineFromRenderer(resultPipeline);
			myModelSoft->myView->getRenderWindow()->Render();
		}
		for (int i = 0; i < receiveVertexNum; i++) {
			myModelSoft->myView->getRenderer()->RemoveActor(vertexActors[i]);
		}
		myModelSoft->myView->getRenderWindow()->Render();
	}
	myModelSoft->RemovePipelineFromRenderer(stretchPipeline);
	myModelSoft->myView->getInteractorStyle()->setCurveOperation(false);
	close();

}

void curveWidget::OnConfirm()
{
	confirmCreated = true;
	for (int i = 0; i < receiveVertexNum; i++) {
		myModelSoft->myView->getRenderer()->RemoveActor(vertexActors[i]);
	}
	int row = myModelSoft->ui->model->rowCount();
	QStandardItem* item1;
	if (type == 0) {
		item1 = new QStandardItem(QString("曲线绘制(直线)-%1").arg(resultPipeline->GetShapeID()));
	}
	else if(type == 1){
		item1 = new QStandardItem(QString("曲线绘制(圆环)-%1").arg(resultPipeline->GetShapeID()));
	}
	else if (type == 2) {
		item1 = new QStandardItem(QString("曲线绘制(椭圆)-%1").arg(resultPipeline->GetShapeID()));
	}
	else {
        item1 = new QStandardItem(QString("曲线绘制(抛物线)-%1").arg(resultPipeline->GetShapeID()));
	}
	item1->setEditable(false);
	myModelSoft->ui->model->setItem(row, 0, item1);
	QStandardItem* item2 = new QStandardItem(QString("隐藏"));
	item2->setCheckable(true);
	myModelSoft->ui->model->setItem(row, 1, item2);
	close();

}

void curveWidget::OnModify()
{
	if (modifyStatus) {
		return;
	}
	if (type == 0) { //创建直线
		gp_Pnt p1(vertexPos[0][0], vertexPos[0][1], vertexPos[0][2]);
		gp_Pnt p2(vertexPos[1][0], vertexPos[1][1], vertexPos[0][2]);
		resultPipeline = myModelSoft->makeLine(p1, p2);
		ui->confirmButton->setEnabled(true);
	}
	else if (type == 1) { //创建圆弧
		gp_Pnt p1(vertexPos[0][0], vertexPos[0][1], vertexPos[0][2]);
		gp_Pnt p2(vertexPos[1][0], vertexPos[1][1], vertexPos[0][2]);
		gp_Pnt p3(vertexPos[2][0], vertexPos[2][1], vertexPos[0][2]);
		//判断是否有重合点
        if (p1.IsEqual(p2, 0.0001) || p1.IsEqual(p3, 0.0001) || p2.IsEqual(p3, 0.0001)) {
			return;
		}

		//创建圆弧
		Handle(Geom_TrimmedCurve) arc = GC_MakeArcOfCircle(p1 ,p2, p3);
		//转化成拓补边
        TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(arc);
		resultPipeline = myModelSoft->CreatePipeline(edge, -1, false);
		resultPipeline->Actor()->GetProperty()->SetLineWidth(3);
		modifyStatus = true;
		ui->confirmButton->setEnabled(true);
		myModelSoft->myView->getRenderWindow()->Render();

	}
	else if(type == 2){ //Ellipse
		gp_Pnt center(vertexPos[0][0], vertexPos[0][1], vertexPos[0][2]);
		gp_Pnt s1(vertexPos[1][0], vertexPos[1][1], vertexPos[0][2]);
		gp_Pnt s2(vertexPos[2][0], vertexPos[2][1], vertexPos[0][2]);

		GC_MakeEllipse ellipse(s1, s2, center);// 创建椭圆
		TopoDS_Edge ellipseEdge = BRepBuilderAPI_MakeEdge(ellipse.Value());//转换成拓补边

		resultPipeline = myModelSoft->CreatePipeline(ellipseEdge, -1, false);
		resultPipeline->Actor()->GetProperty()->SetLineWidth(3);
		modifyStatus = true;
		ui->confirmButton->setEnabled(true);
		myModelSoft->myView->getRenderWindow()->Render();

	}
	else if (type == 3) { //Parabola
		gp_Pnt v(vertexPos[0][0], vertexPos[0][1], vertexPos[0][2]);
		gp_Pnt dirVertex(vertexPos[1][0], vertexPos[1][1], vertexPos[1][2]);
		gp_Dir dir(dirVertex.XYZ() - v.XYZ());
		gp_Ax1 d(v, dir);
		gp_Pnt foucs(vertexPos[2][0], vertexPos[2][1], vertexPos[2][2]);
		//d->抛物线的准线 focus->抛物线焦点
		gp_Parab parab(d, foucs);

		/*
		提前显示抛物线
		再去截取抛物线弧
		*/
		
		gp_Pnt p1(vertexPos[3][0], vertexPos[3][1], vertexPos[3][2]);
		gp_Pnt p2(vertexPos[4][0], vertexPos[4][1], vertexPos[4][2]);

		/*parab:表示抛物线
		p1抛物线弧的起点
		p2抛物线弧的终点
		最后的bool表示抛物线弧的方向是否与抛物线一致*/
		GC_MakeArcOfParabola parabola(parab, p1, p2, true);

		TopoDS_Edge ellipseEdge = BRepBuilderAPI_MakeEdge(parabola.Value());//转换成拓补边

		resultPipeline = myModelSoft->CreatePipeline(ellipseEdge, -1, false);
		resultPipeline->Actor()->GetProperty()->SetLineWidth(3);
		modifyStatus = true;
		ui->confirmButton->setEnabled(true);
		myModelSoft->myView->getRenderWindow()->Render();
	}
	

}

void curveWidget::OnSelVertex()
{
	myModelSoft->myView->getInteractorStyle()->setSelectionMode(SM_Vertex);
	myModelSoft->changeSelector(SM_Vertex);
	myModelSoft->myView->getInteractorStyle()->setCurrSelector(myModelSoft->currSelector);
	myModelSoft->myView->getInteractorStyle()->setCurveOperation(true);
}


void curveWidget::OnCancelSelVertex()
{
}


void curveWidget::OnBoolOPChange(int index)
{
    type = index;

	//删除之前选择点以及创建的曲线
	if (!resultPipeline.IsNull())
	{
		myModelSoft->RemovePipelineFromRenderer(resultPipeline);
		myModelSoft->myView->getRenderWindow()->Render();
	}
	for (int i = 0; i < receiveVertexNum; i++) {
		myModelSoft->myView->getRenderer()->RemoveActor(vertexActors[i]);
	}
	myModelSoft->myView->getRenderWindow()->Render();
}

